From 4650194d207126abcf199ecab8347b985688c162 Mon Sep 17 00:00:00 2001 From: Nipunn Koorapati Date: Sat, 12 Nov 2016 18:55:07 -0800 Subject: [PATCH] Added back __CARGO_DEFAULT_LIB_METADATA handling with comment + test --- src/cargo/ops/cargo_rustc/context.rs | 22 ++++++- tests/build.rs | 86 ++++++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/src/cargo/ops/cargo_rustc/context.rs b/src/cargo/ops/cargo_rustc/context.rs index 4359cbc14..a1552d636 100644 --- a/src/cargo/ops/cargo_rustc/context.rs +++ b/src/cargo/ops/cargo_rustc/context.rs @@ -308,11 +308,31 @@ impl<'a, 'cfg> Context<'a, 'cfg> { } /// Get the metadata for a target in a specific profile + /// We build to the path: "{filename}-{target_metadata}" + /// We use a linking step to link/copy to a predictable filename + /// like `target/debug/libfoo.{a,so,rlib}` and such. pub fn target_metadata(&self, unit: &Unit) -> Option { // No metadata for dylibs because of a couple issues // - OSX encodes the dylib name in the executable // - Windows rustc multiple files of which we can't easily link all of them - if !unit.profile.test && unit.target.is_dylib() { + // + // Two expeptions + // 1) Upstream dependencies (we aren't exporting + need to resolve name conflict) + // 2) __CARGO_DEFAULT_LIB_METADATA env var + // + // Note, though, that the compiler's build system at least wants + // path dependencies (eg libstd) to have hashes in filenames. To account for + // that we have an extra hack here which reads the + // `__CARGO_DEFAULT_METADATA` environment variable and creates a + // hash in the filename if that's present. + // + // This environment variable should not be relied on! It's + // just here for rustbuild. We need a more principled method + // doing this eventually. + if !unit.profile.test && + unit.target.is_dylib() && + unit.pkg.package_id().source_id().is_path() && + !env::var("__CARGO_DEFAULT_LIB_METADATA").is_ok() { return None; } diff --git a/tests/build.rs b/tests/build.rs index ac274de22..decfa8ed5 100644 --- a/tests/build.rs +++ b/tests/build.rs @@ -417,6 +417,8 @@ fn cargo_compile_with_nested_deps_inferred() { .unwrap(); assert_that(&p.bin("foo"), existing_file()); + assert_that(&p.bin("libbar.rlib"), is_not(existing_file())); + assert_that(&p.bin("libbaz.rlib"), is_not(existing_file())); assert_that( process(&p.bin("foo")), @@ -476,6 +478,8 @@ fn cargo_compile_with_nested_deps_correct_bin() { .unwrap(); assert_that(&p.bin("foo"), existing_file()); + assert_that(&p.bin("libbar.rlib"), is_not(existing_file())); + assert_that(&p.bin("libbaz.rlib"), is_not(existing_file())); assert_that( process(&p.bin("foo")), @@ -544,6 +548,8 @@ fn cargo_compile_with_nested_deps_shorthand() { .unwrap(); assert_that(&p.bin("foo"), existing_file()); + assert_that(&p.bin("libbar.rlib"), is_not(existing_file())); + assert_that(&p.bin("libbaz.rlib"), is_not(existing_file())); assert_that( process(&p.bin("foo")), @@ -612,6 +618,8 @@ fn cargo_compile_with_nested_deps_longhand() { assert_that(p.cargo_process("build"), execs()); assert_that(&p.bin("foo"), existing_file()); + assert_that(&p.bin("libbar.rlib"), is_not(existing_file())); + assert_that(&p.bin("libbaz.rlib"), is_not(existing_file())); assert_that(process(&p.bin("foo")), execs().with_stdout("test passed\n")); @@ -754,6 +762,84 @@ fn ignores_carriage_return_in_lockfile() { execs().with_status(0)); } +#[test] +fn cargo_default_env_metadata_env_var() { + // Ensure that path dep + dylib + env_var get metadata + // (even though path_dep + dylib should not) + let p = project("foo") + .file("Cargo.toml", r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + + [dependencies.bar] + path = "bar" + "#) + .file("src/lib.rs", "// hi") + .file("bar/Cargo.toml", r#" + [package] + name = "bar" + version = "0.0.1" + authors = [] + + [lib] + name = "bar" + crate_type = ["dylib"] + "#) + .file("bar/src/lib.rs", "// hello"); + + // No metadata on libbar since it's a dylib path dependency + assert_that(p.cargo_process("build").arg("-v"), + execs().with_status(0).with_stderr(&format!("\ +[COMPILING] bar v0.0.1 ({url}[/]bar) +[RUNNING] `rustc bar[/]src[/]lib.rs --crate-name bar --crate-type dylib \ + -C prefer-dynamic -g \ + -C metadata=[..] \ + --out-dir [..] \ + --emit=dep-info,link \ + -L dependency={dir}[/]target[/]debug[/]deps` +[COMPILING] foo v0.0.1 ({url}) +[RUNNING] `rustc src[/]lib.rs --crate-name foo --crate-type lib -g \ + -C metadata=[..] \ + -C extra-filename=[..] \ + --out-dir [..] \ + --emit=dep-info,link \ + -L dependency={dir}[/]target[/]debug[/]deps \ + --extern bar={dir}[/]target[/]debug[/]deps[/]libbar.dylib` +[FINISHED] debug [unoptimized + debuginfo] target(s) in [..] +", +dir = p.root().display(), +url = p.url(), +))); + + assert_that(p.cargo_process("clean"), execs().with_status(0)); + + // If you set the env-var, then we expect metadata on libbar + assert_that(p.cargo_process("build").arg("-v").env("__CARGO_DEFAULT_LIB_METADATA", "1"), + execs().with_status(0).with_stderr(&format!("\ +[COMPILING] bar v0.0.1 ({url}[/]bar) +[RUNNING] `rustc bar[/]src[/]lib.rs --crate-name bar --crate-type dylib \ + -C prefer-dynamic -g \ + -C metadata=[..] \ + --out-dir [..] \ + --emit=dep-info,link \ + -L dependency={dir}[/]target[/]debug[/]deps` +[COMPILING] foo v0.0.1 ({url}) +[RUNNING] `rustc src[/]lib.rs --crate-name foo --crate-type lib -g \ + -C metadata=[..] \ + -C extra-filename=[..] \ + --out-dir [..] \ + --emit=dep-info,link \ + -L dependency={dir}[/]target[/]debug[/]deps \ + --extern bar={dir}[/]target[/]debug[/]deps[/]libbar-[..].dylib` +[FINISHED] debug [unoptimized + debuginfo] target(s) in [..] +", +dir = p.root().display(), +url = p.url(), +))); +} + #[test] fn crate_env_vars() { let p = project("foo") -- 2.30.2